package com.autumn.util.data;

import java.util.Date;
import java.util.List;

import com.autumn.common.api.domain.entities.IEntity;
import com.autumn.common.api.domain.entities.auditing.IGmtCreate;
import com.autumn.common.api.domain.entities.auditing.IGmtDelete;
import com.autumn.common.api.domain.entities.auditing.IGmtModified;
import com.autumn.common.api.domain.entities.auditing.ISoftDelete;
import com.autumn.domain.repositories.IEntityRepository;
import com.autumn.mybatis.criterion.SpecifyUpdate;

/**
 * 数据审计帮助
 * 
 * @author 老码农
 *         <p>
 *         Description
 *         </p>
 * @date 2017-12-31 14:02:08
 */
public class DbAuditingUtils {

	/**
	 * 按主键删除
	 * 
	 * @param repository  仓储
	 * @param entityClass 实体类型
	 * @param id          主键
	 * @return
	 */
	public static <TEntity extends IEntity<TPrimaryKey>, TPrimaryKey> int deleteById(
			IEntityRepository<TEntity, TPrimaryKey> repository, Class<TEntity> entityClass, TPrimaryKey id) {
		if (ISoftDelete.class.isAssignableFrom(entityClass)) {
			SpecifyUpdate su = new SpecifyUpdate(entityClass);
			su.eq("id", id).eq("isDelete", false).set("isDelete", true);
			if (IGmtDelete.class.isAssignableFrom(entityClass)) {
				su.set("gmtDelete", new Date());
			}
			return repository.updateBySpecify(su.builderSection());
		} else {
			return repository.deleteByPrimaryKey(id);
		}
	}

	/**
	 * 插入设置属性
	 * 
	 * @param entity 实体
	 */
	public static void insertSetProperty(Object entity) {
		if (entity == null) {
			return;
		}
		Date date = new Date();
		if (entity instanceof IGmtCreate) {
			((IGmtCreate) entity).setGmtCreate(date);
		}
		if (entity instanceof IGmtModified) {
			((IGmtModified) entity).setGmtModified(null);
		}
		if (entity instanceof IGmtDelete) {
			IGmtDelete gmt = (IGmtDelete) entity;
			gmt.setGmtDelete(null);
			gmt.setIsDelete(false);
		} else {
			if (entity instanceof ISoftDelete) {
				((ISoftDelete) entity).setIsDelete(false);
			}
		}
	}

	/**
	 * 插入设置属性列表
	 * 
	 * @param entitys 实体集合
	 */
	public static <T> void insertSetPropertyList(List<T> entitys) {
		if (entitys == null || entitys.size() == 0) {
			return;
		}
		Date date = new Date();
		Class<?> type = entitys.get(0).getClass();
		boolean isGmtCreate = IGmtCreate.class.isAssignableFrom(type);
		boolean isGmtModified = IGmtModified.class.isAssignableFrom(type);
		boolean isSoftDelete = ISoftDelete.class.isAssignableFrom(type);
		boolean isGmtDelete = IGmtDelete.class.isAssignableFrom(type);
		if (isGmtCreate || isGmtModified) {
			for (T t : entitys) {
				if (isGmtCreate) {
					((IGmtCreate) t).setGmtCreate(date);
				}
				if (isGmtModified) {
					((IGmtModified) t).setGmtModified(null);
				}
				if (isGmtDelete) {
					IGmtDelete gmt = (IGmtDelete) t;
					gmt.setGmtDelete(null);
					gmt.setIsDelete(false);
				} else {
					if (isSoftDelete) {
						((ISoftDelete) t).setIsDelete(false);
					}
				}
			}
		}
	}

	/**
	 * 更新设置属性
	 * 
	 * @param entity 实体
	 */
	public static void updateSetProperty(Object entity) {
		if (entity == null) {
			return;
		}
		if (entity instanceof IGmtModified) {
			Date date = new Date();
			IGmtModified gmtModified = (IGmtModified) entity;
			if (entity instanceof IGmtDelete) {
				IGmtDelete gmt = (IGmtDelete) entity;
				if (!gmt.getIsDelete()) {
					gmt.setGmtDelete(null);
					gmt.setIsDelete(false);
				}
			}
			if (entity instanceof ISoftDelete) {
				ISoftDelete soft = (ISoftDelete) entity;
				if (!soft.getIsDelete()) {
					gmtModified.setGmtModified(date);
				}
			} else {
				gmtModified.setGmtModified(date);
			}
		}
	}

	/**
	 * 更新设置属性列表
	 * 
	 * @param entitys 实体集合
	 */
	public static <T> void updateSetPropertyList(List<T> entitys) {
		if (entitys == null || entitys.size() == 0) {
			return;
		}
		Date date = new Date();
		Class<?> type = entitys.get(0).getClass();
		boolean isGmtModified = IGmtModified.class.isAssignableFrom(type);
		boolean isSoftDelete = ISoftDelete.class.isAssignableFrom(type);
		boolean isGmtDelete = IGmtDelete.class.isAssignableFrom(type);
		if (isGmtModified) {
			for (T t : entitys) {
				if (isGmtModified) {
					if (isSoftDelete) {
						ISoftDelete soft = (ISoftDelete) t;
						if (!soft.getIsDelete()) {
							((IGmtModified) t).setGmtModified(date);
						}
					} else {
						((IGmtModified) t).setGmtModified(date);
					}
					if (isGmtDelete) {
						IGmtDelete gmt = (IGmtDelete) t;
						if (!gmt.getIsDelete()) {
							gmt.setGmtDelete(null);
						}
					}
				}
			}
		}
	}

	/**
	 * 删除设置属性
	 * 
	 * @param entity 实体
	 */
	public static void deleteSetProperty(Object entity) {
		if (entity == null) {
			return;
		}
		Class<?> type = entity.getClass();
		if (IGmtDelete.class.isAssignableFrom(type)) {
			Date date = new Date();
			IGmtDelete gmt = (IGmtDelete) entity;
			if (!gmt.getIsDelete()) {
				gmt.setGmtDelete(date);
				gmt.setIsDelete(true);
			}
		} else {
			if (ISoftDelete.class.isAssignableFrom(type)) {
				ISoftDelete soft = (ISoftDelete) entity;
				if (!soft.getIsDelete()) {
					soft.setIsDelete(true);
				}
			}
		}
	}

	/**
	 * 删除设置属性列表
	 * 
	 * @param entitys 实体集合
	 */
	public static <T> void deleteSetPropertyList(List<T> entitys) {
		if (entitys == null || entitys.size() == 0) {
			return;
		}
		Date date = new Date();
		Class<?> type = entitys.get(0).getClass();
		boolean isSoftDelete = ISoftDelete.class.isAssignableFrom(type);
		boolean isGmtDelete = IGmtDelete.class.isAssignableFrom(type);
		if (isGmtDelete) {
			for (T t : entitys) {
				IGmtDelete gmt = (IGmtDelete) t;
				if (!gmt.getIsDelete()) {
					gmt.setGmtDelete(date);
					gmt.setIsDelete(true);
				}
			}
		} else {
			if (isSoftDelete) {
				for (T t : entitys) {
					ISoftDelete soft = (ISoftDelete) t;
					if (!soft.getIsDelete()) {
						soft.setIsDelete(true);
					}
				}
			}
		}
	}

}
